package com.tina.websocket;

import com.alibaba.fastjson.JSON;
import com.tina.config.EndpointConfig;
import com.tina.entity.Orders;
import com.tina.entity.OrdersMsgVo;
import com.tina.exception.CustomerException;
import com.tina.service.IFlowersService;
import com.tina.service.IOrdersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author tina
 * @Time 2020/11/26 下午10:10
 * @Version 1.0
 * @Content
 **/
@Slf4j
@ServerEndpoint(value = "/webscoket/{userName}", configurator = EndpointConfig.class)
@Component
public class WebSocketServer {
    @Autowired
    private IOrdersService ordersService;

    @Autowired
    private IFlowersService flowersService;
    /**
     * 用来存储每个客户端对应的MyWebSocket对象.
     */
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
    /**
     * 用来记录sessionId和该session之间的绑定关系.
     */
    private static Map<String, Session> map = new HashMap<String, Session>();

    /**
     * 当前会话的session.
     */
    private Session session;


    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        map.put(session.getId(), session);
        webSocketSet.add(this);
        sendMessage(new OrdersMsgVo(ordersService.ordersCountNum(), null, null, false));
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        //从set中移除.
        webSocketSet.remove(this);
        map.remove(session.getId());
    }

    /**
     * 收到客户端消息后调用的方法.
     */
    @OnMessage
    public void onMessage(String message, Session session, @PathParam("userName") String userName) {
        //message 不是普通的string ，而是我们定义的SocketMsg json字符串.
        Orders orders = JSON.parseObject(message, Orders.class);
        Session toSession = map.get(session.getId());
        try {
            flowersService.checkFood(orders.getFlowersId());
            String imgurl = ordersService.orderFrom(orders);
            //发送消息.
            toSession.getAsyncRemote().sendText(JSON.toJSONString(new OrdersMsgVo(ordersService.ordersCountNum(), imgurl, null, false)));
        } catch (CustomerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            toSession.getAsyncRemote().sendText(JSON.toJSONString(new OrdersMsgVo(null, null, e.getShopCode().getMessage(), false)));
        }
    }

    /**
     * 错误方法
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误");
        error.printStackTrace();
    }

    /**
     * 实现服务器主动推送
     */
    public void sendMessage(Object message) {
        try {
            this.session.getBasicRemote().sendText(JSON.toJSONString(message));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 实现服务器主动群发消息
     */
    public static void sendInfo(Object message) {
        for (WebSocketServer item : webSocketSet) {
            item.sendMessage(message);
        }
    }


}

